class Node {
  constructor(value, next = null, pre = null) {
    this.value = value;
    this.pre = pre;
    this.next = next;
  }
}

/** 画图自行分析较好 */
class DoublyLinkedList {
  constructor() {
    this.head = null;
    this.tail = null;
    this.length = 0
  }

  prePend(value) {
    const node = new Node(value, this.head);
    if (this.head) {
      this.head.pre = node;
    }
    this.head = node;
    if (!this.tail) {
      this.tail = node;
    }
    this.length ++
    return this;
  }

  append(val) {
    const node = new Node(val, null, this.tail);
    if (this.tail) {
      this.tail.next = node;
    }
    this.tail = node;
    if (!this.head) {
      this.head = node;
    }
    this.length++
    return this;
  }

  find(index) {
    let count = 0;
    let currNode = this.head;
    while (count < index) {
      currNode = currNode.next;
      count++;
    }
    return currNode;
  }

  insert(val, index) {
    const node = new Node(val);
    const relIndex = index < 0 ? 0 : index;
    if (relIndex === 0) {
      this.prePend(node);
    } else {
      const currNode = this.find(relIndex);
      /** 此处打印的结构和insert之后打印的结构一致 */
      console.log(this.head,'head');
      if (currNode) {
        const preCurrNode = currNode.pre;
        currNode.pre = node;
        node.next = currNode;
        node.pre = preCurrNode;
        preCurrNode.next = node;
      } else {
        if (this.tail) {
          this.tail.next = node;
          node.pre = this.tail;
          this.tail = node;
        } else {
          this.head = node;
          this.tail = node;
        }
      }
      this.length++
    }
    return this
  }

  delete(index) {
    if (!this.head) {
      return null
    }
    this.length--
    if (index<0 || index>=this.length) {
      throw new Error('index超界')
    }
    if (index === 0 ) {
      this.head = this.head.next
      this.pre = null
      return this
    }
    if (index === this.length -1) {
      this.tail = this.tail.pre
      this.tail.next = null
      return this
    }
    const currNode = this.find(index)
    currNode.pre.next = currNode.next
    currNode.next.pre = currNode.pre
  }

  reverse() {
    let pre= null
    let next = null
    let current = this.head
    while(current) {
      next = current.next
      pre = current.pre
      current.next = pre
      current.pre = next
      pre = current
      current = next
    }
    this.tail = this.head
    this.head = pre;
    return current
  }
}

const newLink = new DoublyLinkedList();
newLink.append(1);
newLink.append(2);
newLink.append(3);
// newLink.prePend(0);
// newLink.insert("insert", 2);
// newLink.delete(0);
newLink.reverse()
console.log(newLink);
